/*
 * Created by Jaren at 2021/8/18 11:02
 */
import 'package:inmotion_protocol/base/base_factory.dart';
import 'package:inmotion_protocol/common/exceptions.dart';
import 'package:inmotion_protocol/common/vehicle_info.dart';
import 'package:inmotion_protocol/lorin/factory/general/general_message.factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/e10_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/e20_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/e25_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/euc_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/p6_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/v11_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/v12_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/v13_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/v14_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/v18_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/c1_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/le1_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/lr1_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/rs_velo_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/s1_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/scooter/scooter_message_factory.dart';
import 'package:inmotion_protocol/lorin/factory/special/special_message_factory.dart';
import 'package:inmotion_protocol/lorin/lorin_message.dart';
import 'dart:typed_data';
import 'package:inmotion_protocol/util/byte_util.dart';
import 'package:inmotion_protocol/util/device.dart';

import 'special/euc/v6_message_factory.dart';

class LorinMessageFactory with MsgFactory<LorinMessage> {
  /// 专用组MsgFactory实例
  /// 在[init]方法中根据产品型号实例化
  SpecialMessageFactory specialMessageFactory =
      UnknownSpecialMsgFactory.instance;

  LorinMessageFactory();

  @override
  void init(ProductProperty productProperty) {
    model = productProperty.model;
    version = productProperty.versionWrapper;
    if (model.isV11Series()) {
      specialMessageFactory = V11MessageFactory(productProperty);
    } else if (model.isV12Series()) {
      specialMessageFactory = V12MessageFactory(productProperty);
    } else if (model.isV13Series()) {
      specialMessageFactory = V13MessageFactory(productProperty);
    } else if (model.isV14Series()) {
      specialMessageFactory = V14MessageFactory(productProperty);
    } else if (model.isLS1Series()) {
      specialMessageFactory = S1MessageFactory(productProperty);
    } else if (model.isLC1Series()) {
      specialMessageFactory = C1MessageFactory(productProperty);
    } else if (model.isLA1Series()) {
      specialMessageFactory = S1MessageFactory(productProperty);
    } else if (model.isLE1Series()) {
      specialMessageFactory = LE1MessageFactory(productProperty);
    } else if (model.isLR1Series()) {
      specialMessageFactory = LR1MessageFactory(productProperty);
    } else if (model.isRSVeloSeries()) {
      specialMessageFactory = RsVeloMessageFactory(productProperty);
    } else if (model.isE20Series()) {
      specialMessageFactory = E20MessageFactory(productProperty);
    } else if (model.isE10Series() || model.isE15Series()) {
      specialMessageFactory = E10MessageFactory(productProperty);
    } else if (model.isP6Series()) {
      specialMessageFactory = P6MessageFactory(productProperty);
    } else if (model.isV6Series()) {
      specialMessageFactory = V6MessageFactory(productProperty);
    } else if (model.isV12sSeries()) {
      specialMessageFactory = V18MessageFactory(productProperty);
    } else if (model.isV9Series()) {
      specialMessageFactory = E25MessageFactory(productProperty);
    } else {
      throw NotSupportException('');
    }
    specialMessageFactory.initCompact(model.feature.value, version);
  }

  LorinMessage genRequestTBoxEsimListMsg([int? source, int? target]) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genRequestTBoxEsimList();
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genRequestTBoxEsimList();
    }
  }

  LorinMessage genRequestTBoxRealTimeInfoMsg([int? source, int? target]) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genRequestTBoxRealTimeInfo();
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genRequestTBoxRealTimeInfo();
    }
  }

  LorinMessage genRequestTBoxInfoMsg([int? source, int? target]) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genTBoxInfo();
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genTBoxInfo();
    }
  }

  LorinMessage genRequestVehicleSynthesizeRealTimeInfoMsg(
      [int? source, int? target]) {
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genRequestVehicleSynthesizeRealTimeInfo();
  }

  // LorinMessage genRequestTBoxDeviceIdMsg([int? source, int? target]) {
  //   if (specialMessageFactory is EucLorinSpecialMessageFactory) {
  //     return (specialMessageFactory as EucLorinSpecialMessageFactory)
  //         .genTBoxDeviceId();
  //   } else {
  //     return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
  //         .genTBoxDeviceId();
  //   }
  // }

  LorinMessage genRequestTBoxUserInfoMsg([int? source, int? target]) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genTBoxUserInfo();
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genTBoxUserInfo();
    }
  }

  LorinMessage genRebootTBoxMsg(int mode, [int? source, int? target]) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genRebootTBox(mode);
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genRebootTBox(mode);
    }
  }

  LorinMessage genStartUpgradingFirmwareMsg([Uint8ClampedList? para]) {
    // _checkEucMsgFactory();
    // return (specialMessageFactory as EucLorinSpecialMessageFactory)
    //     .genStartUpgradingFirmwareMsg(para);
    if(specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genStartUpgradingFirmwareMsg(para);
    } else if(specialMessageFactory is ScooterLorinSpecialMessageFactory) {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genStartUpgradingFirmwareMsg(para);
    } else {
      throw NotSupportException('');
    }
  }

  LorinMessage genStartTransferFirmwareMsg([Uint8ClampedList? para]) {
    // _checkEucMsgFactory();
    // return (specialMessageFactory as EucLorinSpecialMessageFactory)
    //     .genStartTransferFirmwareMsg(para);
    if(specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genStartTransferFirmwareMsg(para);
    } else if(specialMessageFactory is ScooterLorinSpecialMessageFactory) {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genStartTransferFirmwareMsg(para);
    } else {
      throw NotSupportException('');
    }
  }

  LorinMessage genRequestModelMsg([int? source, int? target]) {
    return LorinGeneralMessageFactory.genGetModelMsg(source, target);
  }

  LorinMessage genRequestSnMsg([int? source, int? target]) {
    return LorinGeneralMessageFactory.genGetSnMsg(source, target);
  }

  LorinMessage genRequestEncryptedKeyMsg([int? source, int? target]) {
    return LorinGeneralMessageFactory.genRequestEncryptedKeyMsg();
  }

  LorinMessage genVerifyCryptKeyMsg(Uint8ClampedList key) {
    return LorinGeneralMessageFactory.genVerifyCryptKeyMsg(key);
  }

  LorinMessage genRequestTBoxDeviceIdMsg([int? target]) {
    return LorinGeneralMessageFactory.genTBoxDeviceId(target);
  }

  LorinMessage genBindingTirePressureSensor([Uint8ClampedList? para]) {
    return LorinGeneralMessageFactory.genBindTirePressureSensor(para);
  }

  LorinMessage genTirePressureWarningOnOffMsg([bool on = true]) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genTirePressureWarningOnOffMsg(on);
    }
    throw NotSupportException('');
  }

  LorinMessage genSetLowTirePressureWarningThresholdMsg(
      int lowPressureAlarmThreshold) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetLowTirePressureAlarmThresholdMsg(
              lowPressureAlarmThreshold);
    }
    throw NotSupportException('');
  }

  LorinMessage genSetLogoLightBrightnessMsg(int brightness) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetLogoLightBrightnessMsg(brightness);
    }
    throw NotSupportException('');
  }

  LorinMessage genSetBermAngleMsg(int angle) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetBermAngleMsg(angle);
    }
    throw NotSupportException('');
  }
  LorinMessage genSetOutputThresholdMsg(int tiltBack, int warning1, int warning2) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetOutputThresholdMsg(tiltBack, warning1, warning2);
    }
    throw NotSupportException('');
  }


  LorinMessage genSetTurnSignalModeMsg(int mode) {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetTurnSignalModeMsg(mode);
    }
    throw NotSupportException('');
  }

  LorinMessage genRequestAllRealTimeDataMsg([int? source, int? target]) {
    return specialMessageFactory.genGetAllRealTimeInfoMsg();
  }

  LorinMessage genRequestHistoryStatisticsMsg(int? index, int? count) {
    Uint8ClampedList? params;
    if (index != null && count != null) {
      params = Uint8ClampedList.fromList([index, count]);
    }
    return specialMessageFactory.genGetHistoryStatisticsMsg(params);
  }

  LorinMessage genRequestTotalStatisticsMsg([int? source, int? target]) {
    return specialMessageFactory.genGetTotalStatisticsMsg();
  }

  LorinMessage genFactoryResetMsg({int level = 1}) {
    return LorinGeneralMessageFactory.genFactoryResetMsg(level);
  }

  LorinMessage genRebootRequestMsg([int? source, int? target]) {
    return LorinGeneralMessageFactory.genRebootMsg(source, target);
  }

  LorinMessage genRebootConfirmMsg([int? source, int? target]) {
    return LorinGeneralMessageFactory.genPowerCtrlConfirmMsg(source, target);
  }

  LorinMessage genRequestLightEffectMsg([int? source, int? target]) {
    _checkV12MsgFactory();
    return (specialMessageFactory as V12MessageFactory)
        .genRequestLightEffectMsg();
  }

  LorinMessage genRequestSettingsMsg([int? source, int? target]) {
    return specialMessageFactory.genGetSettingsMsg();
  }

  LorinMessage genRequestRealTimeErrorMsg([int? source, int? target]) {
    return specialMessageFactory.genGetRealTimeErrorMsg();
  }

  LorinMessage genRequestRealTimeInfoMsg([int? source, int? target]) {
    return specialMessageFactory.genGetRealTimeDataMsg();
  }

  LorinMessage genRequestRealTimeStateMsg([int? source, int? target]) {
    return specialMessageFactory.genGetRealTimeStateMsg();
  }

  LorinMessage genRequestBatteryRealTimeMsg([int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genRequestBatteryRealTimeInfoMsg();
  }

  LorinMessage genRequestVersionMsg([int? source, int? target]) {
    if (isUpdateBMS(target)) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genGetFwVersionMsg(source, target);
    } else {
      return LorinGeneralMessageFactory.genGetFwVersionMsg(source, target);
    }
  }

  LorinMessage genRequestDeviceInfoMsg([int? source, int? target]) {
    return specialMessageFactory.genGetDeviceInfoMsg();
  }

  LorinMessage genRequestDeviceRealTimeInfoMsg([int? source, int? target]) {
    return specialMessageFactory.genGetDeviceRealTimeInfoMsg();
  }

  // BMS 电池升级
  bool isUpdateBMS(int? target) {
    if ((model.isV11Series() ||
            model.isV13Series() ||
            model.isV12sSeries() ||
            model.isV9Series() ||
            model.isP6Series()) &&
        (target == DeviceUtils.lorinVBMS1Device ||
            target == DeviceUtils.lorinVBMS2Device)) {
      return true;
    } else {
      return false;
    }
  }

  LorinMessage genSyncRTCMsg([DateTime? dateTime]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSyncRTCMsg(dateTime ?? DateTime.now());
  }

  LorinMessage genAutoScreenOffOnOffMsg(bool on) {
    if (_checkV12MsgFactory(false)) {
      return (specialMessageFactory as V12MessageFactory)
          .genAutoScreenOffOnOffMsg(on);
    }
    if (_checkV18MsgFactory(false)) {
      return (specialMessageFactory as V18MessageFactory)
          .genAutoScreenOffOnOffMsg(on);
    }
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genAutoScreenOffOnOffMsg(on);
    }
    throw NotSupportException('');
  }

  LorinMessage genStartScooterCalibrationMsg(int which) {
    _checkScooterMsgFactory();
    return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
        .genCalibrateHandleMsg(which);
  }

  LorinMessage genCalibrateIMUMsg() {
    if (_checkS1MsgFactory(false)) {
      return (specialMessageFactory as S1MessageFactory).genCalibrateIMUMsg();
    }
    _checkEucMsgFactory();
    throw NotSupportException('');
  }

  LorinMessage genStartIMUCalibrationMsg(
      {int type0 = 0, int type1 = 0, int type2 = 0}) {
    if (_checkS1MsgFactory(false)) {
      return (specialMessageFactory as S1MessageFactory).genCalibrateIMUMsg();
    }
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genCalibrateIMUMsg(type0, type1, type2);
  }

  LorinMessage genQueryIMUCalibrationResultMsg() {
    if (_checkS1MsgFactory(false)) {
      return (specialMessageFactory as S1MessageFactory)
          .genQueryIMUCalibrationMsg();
    }
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genQueryIMUCalibrationMsg();
  }

  LorinMessage genCruiseOnOffMsg(bool on) {
    _checkScooterMsgFactory();
    return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
        .genCruiseOnOffMsg(on);
  }

  LorinMessage genFanOnOffMsg(bool on) {
    _checkV11MsgFactory();
    return (specialMessageFactory as V11MessageFactory).genFanOnOffMsg(on);
  }

  LorinMessage genFanQuietModeOnOffMsg(bool on) {
    _checkV11MsgFactory();
    return (specialMessageFactory as V11MessageFactory)
        .genFanQuietModeOnOffMsg(on);
  }

  LorinMessage genHacOnOffMsg(bool on) {
    _checkS1MsgFactory();
    return (specialMessageFactory as S1MessageFactory).genHacOnOffMsg(on);
  }

  LorinMessage genHdcOnOffMsg(bool on) {
    _checkS1MsgFactory();
    return (specialMessageFactory as S1MessageFactory).genHdcOnOffMsg(on);
  }

  LorinMessage genHeadlightOnOffMsg(
      {bool? on, bool? lowBeamOn, bool? highBeamOn, int? source, int? target}) {
    return specialMessageFactory.genHeadlightOnOffMsg(
        on: on,
        lowBeamOn: lowBeamOn,
        highBeamOn: highBeamOn,
        source: source,
        target: target);
  }

  LorinMessage genLoadDetectOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genLoadDetectOnOffMsg(on);
  }

  LorinMessage genLockMsg(bool on) {
    return specialMessageFactory.genLockMsg(on);
  }

  LorinMessage genLowBatteryProtectionModeOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genLowBatteryProtectionModeOnOffMsg(on);
  }

  LorinMessage genTboxLowBatLevelWakeUpVehicleModeOnOffMsg(bool on) {
    if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genTboxLowBatLevelWakeUpVehicleModeOnOffMsg(on);
    }
    if (specialMessageFactory is ScooterLorinSpecialMessageFactory) {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genTboxLowBatLevelWakeUpVehicleModeOnOffMsg(on);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of EucLorinSpecialMessageFactory or RsVeloMessageFactory.");
  }

  LorinMessage genShowTboxInfoOnVehicleOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genShowTboxInfoOnVehicleOnOffMsg(on);
  }

  LorinMessage genNoLoadDetectOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genNoLoadDetectOnOffMsg(on);
  }

  LorinMessage genQueryScooterCalibrationResultMsg(int which) {
    _checkScooterMsgFactory();
    return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
        .genQueryHandleCalibrationResultMsg(which);
  }

  LorinMessage genRemainderRangeEstimateOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genRemainderRangeEstimateOnOffMsg(on);
  }

  LorinMessage genSafeSpeedLimitOnOffMsg(bool on) {
    if (specialMessageFactory is ScooterLorinSpecialMessageFactory) {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genSafeSpeedLimitOnOffMsg(on);
    } else if (specialMessageFactory is EucLorinSpecialMessageFactory) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genSafeSpeedLimitOnOffMsg(on);
    } else {
      throw UnsupportedError(
          "Current message factory instance is not a subtype of ScooterLorinSpecialMessageFactory or EucLorinSpecialMessageFactory.");
    }
  }

  LorinMessage genBermAngleModeOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genBermAngleModeOnOffMsg(on);
  }

  LorinMessage genAutoHeadlightOnOffMsg(bool on) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genAutoHeadlightOnOffMsg(on);
  }

  LorinMessage genAutoLowHighBeamOnOffMsg(bool on) {
    _checkV12MsgFactory();
    return (specialMessageFactory as V12MessageFactory)
        .genAutoLowHighBeamOnOffMsg(on);
  }

  LorinMessage genSetAutoHeadlightBrightnessThrMsg(int lowThr, int highThr) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetAutoHeadlightBrightnessThrMsg(lowThr, highThr);
  }

  LorinMessage genSetHeadlightBrightnessMsg(
      {int? brightness, int? lowBeamBrightness, int? highBeamBrightness}) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetHeadlightBrightnessMsg(
            brightness: brightness,
            lowBeamBrightness: lowBeamBrightness,
            highBeamBrightness: highBeamBrightness);
  }

  LorinMessage genSetDeviceNameMsg(String name) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetDeviceNameMsg(name);
  }

  LorinMessage genRequestDeviceNameMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genRequestDeviceNameMsg();
  }

  LorinMessage genSetDriveModeMsg(int driveMode) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetDriveModeMsg(driveMode);
  }

  LorinMessage genSetPasswordMsg(String pwd,
      [int? type, int? source, int? target]) {
    if (_checkEucMsgFactory(false)) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genSetPasswordMsg(type!, pwd);
    } else {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genSetPasswordMsg(type!, pwd);
    }
  }

  LorinMessage genSetPasswordTypeMsg(int type) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetPasswordTypeMsg(type);
  }

  LorinMessage genSetPedalSensitivityMsg(int sensitivity,
      [int? sensitivity2, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetPedalSensitivityMsg(sensitivity, sensitivity2!);
  }

  LorinMessage genSetPitchAngleZeroMsg(int angle) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetPitchAngleMsg(angle);
  }

  LorinMessage genSetRidingModeMsg(int mode) {
    return specialMessageFactory.genSetRidingModeMsg(mode);
  }

  LorinMessage genSetSoundPackIdMsg(int id) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetSoundPackIdMsg(id);
  }

  LorinMessage genSetSoundWaveSensitivityMsg(int sensitivity) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetSoundWaveSensitivityMsg(sensitivity);
  }

  LorinMessage genSetSpeedUnitMsg(int unit) {
    if (_checkScooterMsgFactory(false)) {
      return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
          .genSetSpeedUnitMsg(unit);
    }
    if (_checkV14MsgFactory(false)) {
      return (specialMessageFactory as V14MessageFactory)
          .genSetSpeedUnitMsg(unit);
    }
    if (_checkE25MsgFactory(false)) {
      return (specialMessageFactory as E25MessageFactory)
          .genSetSpeedUnitMsg(unit);
    }
    throw NotSupportException('');
  }

  LorinMessage genSetDaytimeRunningLightMsg(bool on) {
    if (_checkE25MsgFactory(false)) {
      return (specialMessageFactory as E25MessageFactory)
          .genDaytimeRunningLightMsg(on);
    }
    if (_checkV18MsgFactory(false)) {
      return (specialMessageFactory as V18MessageFactory)
          .genDaytimeRunningLightMsg(on);
    }
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genDaytimeRunningLightMsg(on);
    }
    throw NotSupportException('');
  }

  LorinMessage genTwoBatteryModeMsg(bool on) {
    if (_checkV14MsgFactory(false)) {
      return (specialMessageFactory as V14MessageFactory)
          .genSetTwoBatteryModeMsg(on);
    }
    throw NotSupportException('');
  }

  LorinMessage genDisableChargeDangerAlertMsg() {
    if (_checkV11MsgFactory(false)) {
      return (specialMessageFactory as V11MessageFactory)
          .genDisableChargeDangerAlertMsg();
    }
    if (_checkV12MsgFactory(false)) {
      return (specialMessageFactory as V12MessageFactory)
          .genDisableChargeDangerAlertMsg();
    }
    throw NotSupportException('');
  }

  LorinMessage genSetWarningLimitSpeedMsg(int speed1, int speed2) {
    if (_checkV12MsgFactory(false)) {
      return (specialMessageFactory as V12MessageFactory)
          .genSetWarningLimitSpeedMsg(speed1, speed2);
    }
    if (_checkV18MsgFactory(false)) {
      return (specialMessageFactory as V18MessageFactory)
          .genSetWarningLimitSpeedMsg(speed1, speed2);
    }
    if (_checkE25MsgFactory(false)) {
      return (specialMessageFactory as E25MessageFactory)
          .genSetWarningLimitSpeedMsg(speed1, speed2);
    }
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSetWarningLimitSpeedMsg(speed1, speed2);
    }
    throw NotSupportException('');
  }

  LorinMessage genSearchTirePressureSensorMsg() {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genSearchTirePressureSensorMsg();
    }
    throw NotSupportException("");
  }

  LorinMessage genResetTirePressureSensorSearchResultMsg() {
    if (_checkP6MsgFactory(false)) {
      return (specialMessageFactory as P6MessageFactory)
          .genResetTirePressureSensorSearchResultMsg();
    }
    throw NotSupportException("");
  }

  LorinMessage genSetSpeedLimitMsg(int speedLimit, [int? speedLimit2]) {
    return specialMessageFactory.genSetSpeedLimitMsg(speedLimit, speedLimit2);
  }

  LorinMessage genSetSpeedLimitOfAssistModeMsg(int speedLimit) {
    _checkC1MsgFactory();
    return (specialMessageFactory as C1MessageFactory)
        .genSetSpeedLimitOfAssistModeMsg(speedLimit);
  }

  LorinMessage genSetAutoLowHighBeamSwitchSpeedThrMsg(int speedThr) {
    _checkV12MsgFactory();
    return (specialMessageFactory as V12MessageFactory)
        .genSetAutoLowHighBeamSwitchSpeedThrMsg(speedThr);
  }

  LorinMessage genSetSpeedingBrakingSensitivityMsg(int speeding, int braking) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetSpeedingBrakingSensitivityMsg(speeding, braking);
  }

  LorinMessage genSetStandbyTimeMsg(int seconds) {
    if (_checkEucMsgFactory(false)) {
      return (specialMessageFactory as EucLorinSpecialMessageFactory)
          .genSetStandbyTimeMsg(seconds);
    }
    if (_checkLR1MsgFactory(false)) {
      return (specialMessageFactory as LR1MessageFactory)
          .genSetStandbyTimeMsg(seconds);
    }
    if (_checkRsVeloMsgFactory(false)) {
      return (specialMessageFactory as RsVeloMessageFactory)
          .genSetStandbyTimeMsg(seconds);
    }
    throw NotSupportException("Not support for $specialMessageFactory.");
  }

  LorinMessage genSetVolumeMsg(int volume) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetVolumeMsg(volume);
  }

  LorinMessage genSoundPackOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSoundPackOnOffMsg(on);
  }

  LorinMessage genSoundWaveOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSoundWaveOnOffMsg(on);
  }

  LorinMessage genSpeedingBrakingOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSpeedingBrakingOnOffMsg(on);
  }

  LorinMessage genSpinKillOnOffMsg([bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSpinKillOnOffMsg(on);
  }

  LorinMessage genTransportationModeOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genTransportationModeOnOffMsg(on);
  }

  LorinMessage genUsbPowerOnOffMsg([bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genUsbPowerOnOffMsg(on);
  }

  LorinMessage genZeroSpeedupOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkScooterMsgFactory();
    return (specialMessageFactory as ScooterLorinSpecialMessageFactory)
        .genZeroSpeedupOnOffMsg(on);
  }

  LorinMessage genAssistBalanceOnOffMsg(
      [bool on = true, int? source, int? target]) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genAssistBalanceOnOffMsg(on);
  }

  LorinMessage genSetLightEffectIdMsg(int id) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genSetLightEffectIdMsg(id);
  }

  LorinMessage genSetLightEffectModeMsg(
      {bool? onOff,
      int? mode,
      int? paramColor,
      int? paramMode,
      int? source,
      int? target}) {
    if (_checkV11MsgFactory(false) || _checkV13MsgFactory(false)) {
      if (onOff == null) {
        throw InvalidParamException(
            'Param [onOff] could not be null on V11 or V13.');
      }
      return specialMessageFactory.genSetLightEffectModeMsg(onOff ? 1 : 0);
    }
    if (_checkV12MsgFactory(false) ||
        _checkV18MsgFactory(false) ||
        _checkE25MsgFactory(false) ||
        _checkP6MsgFactory(false)) {
      if (mode == null) {
        throw InvalidParamException('Param [mode] could not be null on V12.');
      }
      Uint8ClampedList param;
      if (paramColor != null) {
        param = ByteUtil.num2Bytes(paramColor, 3);
      } else if (paramMode != null) {
        param = Uint8ClampedList.fromList([0, 0, 0, paramMode]);
      } else {
        param = Uint8ClampedList.fromList([0xFF, 0xFF, 0xFF, 0xFF]);
      }
      return specialMessageFactory.genSetLightEffectModeMsg(mode, param);
    }
    if (mode == null) {
      throw InvalidParamException(
          'Param [mode] could not be null when product model is not V11, V12 and V13.');
    }
    return specialMessageFactory.genSetLightEffectModeMsg(mode);
  }

  LorinMessage genPlaySoundItemMsg(int index) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genPlaySoundItemMsg(index);
  }

  LorinMessage genSetMaxChargeLevelMsg(int level) {
    _checkV13MsgFactory();
    return (specialMessageFactory as V13MessageFactory)
        .genSetMaxChargeLevelMsg(level);
  }

  LorinMessage genSetMaxDCOutputLevelMsg(int level) {
    _checkV13MsgFactory();
    return (specialMessageFactory as V13MessageFactory)
        .genSetMaxDcOutputLevelMsg(level);
  }

  LorinMessage genSetUSBModeMsg(int level) {
    _checkV13MsgFactory();
    return (specialMessageFactory as V13MessageFactory).genSetUsbModeMsg(level);
  }

  LorinMessage genRequestBMSCellsVoltageMsg(int target) {
    _checkSimpleBMSFeatureTrait();
    return (specialMessageFactory as SimpleBMSFeatureMsgFactoryTrait)
        .genRequestBMSCellsVoltageInfoMsg(target);
  }

  LorinMessage genRequestBMSDateMsg(int target) {
    _checkFullBMSFeatureTrait();
    return (specialMessageFactory as FullBMSFeatureMsgFactoryTrait)
        .genRequestBMSDateMsg(target);
  }

  LorinMessage genRequestBMSFixedInfoMsg(int target) {
    _checkFullBMSFeatureTrait();
    return (specialMessageFactory as FullBMSFeatureMsgFactoryTrait)
        .genRequestBMSFixedInfoMsg(target);
  }

  LorinMessage genRequestBMSLogMsg(int target, int index) {
    _checkBMSLogTrait();
    return (specialMessageFactory as BMSLogMsgFactoryTrait<LorinMessage>)
        .genRequestBMSLogMsg(target, index);
  }

  LorinMessage genRequestBMSLogCountMsg(int target) {
    _checkBMSLogTrait();
    return (specialMessageFactory as BMSLogMsgFactoryTrait<LorinMessage>)
        .genRequestBMSLogCountMsg(target);
  }

  LorinMessage genRequestBMSRealTimeInfoMsg(int target) {
    _checkFullBMSFeatureTrait();
    return (specialMessageFactory as FullBMSFeatureMsgFactoryTrait)
        .genRequestBMSRealTimeInfoMsg(target);
  }

  LorinMessage genStartMotorAutoCalibrationMsg(
      {int hallOffsetCalibrate = 1, int hallSectorCalibrate = 1}) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genStartMotorAutoCalibrationMsg(
            hallOffsetCalibrate, hallSectorCalibrate);
  }

  LorinMessage genQueryMotorAutoCalibrationResultMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genQueryMotorAutoCalibrationResultMsg();
  }

  LorinMessage genResetMotorAutoCalibrationEffectMsg(
      {int hallOffset = 1, int hallSector = 1}) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genResetMotorAutoCalibrationEffectMsg(
            hallOffset: hallOffset, hallSector: hallSector);
  }

  LorinMessage genStopMotorAutoCalibrationMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genStopMotorAutoCalibrationMsg();
  }

  LorinMessage genStartMotorSelfCheckMsg({int method = 1}) {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genStartMotorSelfCheckMsg(method: method);
  }

  LorinMessage genQueryMotorSelfCheckResultMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genQueryMotorSelfCheckResultMsg();
  }

  LorinMessage genStartBatteryCalibrationMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genStartBatteryCalibrationMsg();
  }

  LorinMessage genQueryBatteryCalibrationResultMsg() {
    _checkEucMsgFactory();
    return (specialMessageFactory as EucLorinSpecialMessageFactory)
        .genQueryBatteryCalibrationResultMsg();
  }

  LorinMessage genAccForceMsg(int accForce, {int? type}) {
    if (type == null) {
      throw InvalidParamException("Param [type] is required.");
    }
    if (_checkLR1MsgFactory(false)) {
      return (specialMessageFactory as LR1MessageFactory)
          .genAccForceMsg(type, accForce);
    }
    if (_checkRsVeloMsgFactory(false)) {
      return (specialMessageFactory as RsVeloMessageFactory)
          .genAccForceMsg(type, accForce);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of RsVeloMessageFactory or LR1MessageFactory.");
  }

  LorinMessage genBrakeForceMsg(int brakeForce, {int? type}) {
    if (_checkLE1MsgFactory(false)) {
      if (type == null) {
        throw InvalidParamException("Param [type] is required.");
      }
      return (specialMessageFactory as LE1MessageFactory)
          .genBrakeForceMsg(type, brakeForce);
    }
    if (_checkLR1MsgFactory(false)) {
      if (type == null) {
        throw InvalidParamException("Param [type] is required.");
      }
      return (specialMessageFactory as LR1MessageFactory)
          .genBrakeForceMsg(type, brakeForce);
    }

    if (_checkRsVeloMsgFactory(false)) {
      if (type == null) {
        throw InvalidParamException("Param [type] is required.");
      }
      return (specialMessageFactory as RsVeloMessageFactory)
          .genBrakeForceMsg(type, brakeForce);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of LE1MessageFactory or LR1MessageFactory.");
  }

  LorinMessage genOnePedalModeOnOffMsg(bool on) {
    if (_checkLR1MsgFactory(false)) {
      return (specialMessageFactory as LR1MessageFactory)
          .genOnePedalModeOnOffMsg(on);
    }
    if (_checkRsVeloMsgFactory(false)) {
      return (specialMessageFactory as RsVeloMessageFactory)
          .genOnePedalModeOnOffMsg(on);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of RsVeloMessageFactory or LR1MessageFactory.");
  }

  LorinMessage genBrakeFirstModeOnOffMsg(bool on) {
    if (_checkLR1MsgFactory(false)) {
      return (specialMessageFactory as LR1MessageFactory)
          .genBrakeFirstModeOnOffMsg(on);
    }
    if (_checkRsVeloMsgFactory()) {
      return (specialMessageFactory as RsVeloMessageFactory)
          .genBrakeFirstModeOnOffMsg(on);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of RsVeloMessageFactory or LR1MessageFactory.");
  }

  LorinMessage genSetParkTimeMsg(int seconds) {
    if (_checkLR1MsgFactory(false)) {
      return (specialMessageFactory as LR1MessageFactory)
          .genSetParkTimeMsg(seconds);
    }
    if (_checkRsVeloMsgFactory()) {
      return (specialMessageFactory as RsVeloMessageFactory)
          .genSetParkTimeMsg(seconds);
    }
    throw UnsupportedError(
        "Current message factory instance is not a subtype of RsVeloMessageFactory or LR1MessageFactory.");
  }

  LorinMessage genSetMaxChargeCurrentMsg(int currentAc220, int currentAc110) {
    _checkP6MsgFactory();
    return (specialMessageFactory as P6MessageFactory)
        .genSetMaxChargeCurrentMsg(currentAc220, currentAc110);
  }

  LorinMessage genSetChargeLimitMsg(int limit) {
    _checkP6MsgFactory();
    return (specialMessageFactory as P6MessageFactory)
        .genSetChargeLimitMsg(limit);
  }



  _checkBMSLogTrait([bool throwException = true]) {
    if (specialMessageFactory is! BMSLogMsgFactoryTrait) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of BMSMsgFactoryTrait. ${specialMessageFactory.runtimeType}");
      }
      return false;
    }
    return true;
  }

  _checkScooterMsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! ScooterLorinSpecialMessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of ScooterLorinSpecialMessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkS1MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! S1MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of S1MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkC1MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! C1MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of C1MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkLE1MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! LE1MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of LE1MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkLR1MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! LR1MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of LR1MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkRsVeloMsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! RsVeloMessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of RsVeloMessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkEucMsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! EucLorinSpecialMessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of EucLorinSpecialMessageFactory. ${specialMessageFactory.runtimeType}");
      }
      return false;
    }
    return true;
  }

  _checkV11MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! V11MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V11MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkV12MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is V12MessageFactory ||
        specialMessageFactory is E20MessageFactory ||
        specialMessageFactory is V6MessageFactory ||
        specialMessageFactory is E10MessageFactory) {
      return true;
    } else {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V12MessageFactory.");
      }
      return false;
    }
  }

  _checkV18MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is V18MessageFactory) {
      return true;
    } else {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V18MessageFactory.");
      }
      return false;
    }
  }

  _checkP6MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is P6MessageFactory) {
      return true;
    } else {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V18MessageFactory.");
      }
      return false;
    }
  }

  _checkE25MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is E25MessageFactory) {
      return true;
    } else {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of E25MessageFactory.");
      }
      return false;
    }
  }

  _checkV13MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! V13MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V13MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkV14MsgFactory([bool throwException = true]) {
    if (specialMessageFactory is! V14MessageFactory) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of V14MessageFactory.");
      }
      return false;
    }
    return true;
  }

  _checkFullBMSFeatureTrait([bool throwException = true]) {
    if (specialMessageFactory is! FullBMSFeatureMsgFactoryTrait) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of FullBMSFeatureMsgFactoryTrait.");
      }
      return false;
    }
    return true;
  }

  _checkSimpleBMSFeatureTrait([bool throwException = true]) {
    if (specialMessageFactory is! SimpleBMSFeatureMsgFactoryTrait) {
      if (throwException) {
        throw UnsupportedError(
            "Current message factory instance is not a subtype of SimpleBMSFeatureMsgFactoryTrait.");
      }
      return false;
    }
    return true;
  }
}
